﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using ElectronicCommerce.Framework.Payment.Contract.DataContract;
using ElectronicCommerce.Framework.Payment.Data;
using ElectronicCommerce.Framework.Payment.Utility;
using ElectronicCommerce.Framework.Web.ResourceManagement;

namespace ElectronicCommerce.Framework.Payment.PayEntry
{
    public abstract class PayEntryBase
    {
        public static readonly bool EnableFileLogger = false;
        /// <summary>
        /// 发送支付请求
        /// </summary>
        /// <param name="paymentRequest"></param>
        protected PaymentRequest SendRequest(PaymentRequest paymentRequest)
        {
            // 分析网关地址(Prodct/Test)
            RefreshGatewayAddress(paymentRequest);

            switch (paymentRequest.Gateway.RequestType)
            {
                case GatewayRequestType.HttpGet:
                    SendHttpGetRequest(paymentRequest);
                    break;
                case GatewayRequestType.HttpPost:
                    SendHttpPostRequest(paymentRequest);
                    break;
            }
            return paymentRequest;
        }

        /// <summary>
        /// 以HttpGet方式发送支付请求
        /// </summary>
        /// <param name="request"></param>
        private void SendHttpGetRequest(PaymentRequest request)
        {
            UrlBuilder url = new UrlBuilder(Encoding.GetEncoding(request.ContentEncoding));
            string gateway = url.BuildUrl(request.Gateway.Address, GetServiceParams(request));
            request.RequestText = gateway;
            PaymentLogger.LogPaymentRequest(request);
            HttpContext.Current.Response.Redirect(gateway, true);
        }

        /// <summary>
        /// 以HttpPost方式发送支付请求
        /// </summary>
        /// <param name="request"></param>
        private void SendHttpPostRequest(PaymentRequest request)
        {
            StringBuilder sb = new StringBuilder();
            NameValueCollection serviceParams = GetServiceParams(request);
            foreach (string key in serviceParams)
            {
                sb.Append(FormHelper.CreateHiddenField(key, serviceParams[key]));
            }
            sb.Append("<input type='submit' style='display:none' />");
            string formContent = FormHelper.CreateForm(sb.ToString(), request.Gateway.Address);
            request.RequestText = formContent;
            PaymentLogger.LogPaymentRequest(request);
            FormHelper.SubmitForm(request.ContentEncoding, formContent);
        }

        /// <summary>
        /// 发送同步请求
        /// </summary>
        /// <param name="paymentRequest"></param>
        protected string SendSyncRequest(PaymentRequest paymentRequest)
        {
            string httpMethod = "GET";
            switch (paymentRequest.Gateway.RequestType)
            {
                case GatewayRequestType.HttpGet:
                    httpMethod = "GET";
                    break;
                case GatewayRequestType.HttpPost:
                    httpMethod = "POST";
                    break;
            }

            // 分析网关地址(Prodct/Test)
            RefreshGatewayAddress(paymentRequest);

            return HttpUtils.SendSyncRequest(paymentRequest.Gateway.Address, GetServiceParams(paymentRequest),
                httpMethod, Encoding.GetEncoding(paymentRequest.ContentEncoding));
        }

        /// <summary>
        /// 通知网关支付结果
        /// </summary>
        /// <param name="message"></param>
        protected void NotifyGatewayPaymentResult(string message)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.AddHours(-1));
            HttpContext.Current.Response.CacheControl = "no-cache";
            HttpContext.Current.Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
            HttpContext.Current.Response.Cache.SetNoStore();

            HttpContext.Current.Response.Write(message);
            HttpContext.Current.Response.End();
        }

        /// <summary>
        /// 从公共入口参数转化为具体支付的入口参数
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected abstract NameValueCollection GetServiceParams(PaymentRequest request);

        /// <summary>
        /// 获取网关产品地址
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected abstract string GetProductGatewayAddress(PaymentRequest request);

        /// <summary>
        /// 获取网关测试地址
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual string GetTestGatewayAddress(PaymentRequest request)
        {
            throw new PaymentException(PaymentExceptionType.NoTestGatewayAddress);
        }

        #region Helper

        /// <summary>
        /// 分析网关地址
        /// </summary>
        /// <param name="request"></param>
        private void RefreshGatewayAddress(PaymentRequest request)
        {
            if (request.EnvType == GatewayEnvType.Product)
            {
                request.Gateway.Address = GetProductGatewayAddress(request);
            }
            else if (request.EnvType == GatewayEnvType.Test)
            {
                request.Gateway.Address = GetTestGatewayAddress(request);
            }
        }

        #endregion
    }
}
